'''
This implementation of translator's assistant will suggests a list of ranked
translation possibilities given a source sentence and a partial translation.

When user provide a source sentence with vocabularies which are not presented
in provided training data, the system will return nothing for the translation 
of that sentence.

The Giza data we used in this process of development is quite small with only 
about 1k vocabulary size. Nevertheless, the observed behavior of the system 
looks normal and we believe the system will perform better if we have given 
larger training data.

Created on May 31, 2010

@author: Guan Gui, Will Zhang
$LastChangedBy: wilzzha $
'''

from language_model import LanguageModel
from reordering_model import ReorderingModel
from translation_model import TranslationModel
from decoder import Decoder
from textwrap import fill
import sys

__version__ = "$Rev: 374 $"
        

def main():
    import sys
    # prepare training data for language model and translation model
    sys.path.append('../../clir/')
    from aligned_parser import GizaReader
    data = GizaReader('../../data/giza/', 'alignment-en-fr')
    
    # instantiate translation model 
    tm = TranslationModel(data)
    
    # n for n-gram language model
    n = 2
    # instantiate language model
    lm = LanguageModel(n, data)
    
    # alpha for reordering model
    alpha = 0.75
    # instantiate reordering model
    rm = ReorderingModel(alpha)
    
    # decoder_stack_threshold for decoder stacks
    decoder_stack_threshold = 5
    
    # the number of results will be produced to output
    num_results = 10
    
    translated_src_mask = None
    last_translated_index = None
    # interactive command line input
    print fill("Please enter the full source sentence:", 79)
    src_sent = to_unicode_or_bust(raw_input(), sys.stdin.encoding).split()
    for i, word in enumerate(src_sent):
        print word.encode(sys.stdout.encoding), "(%d)" % i, 
    print
    
    print fill("Please enter the partial translation:", 79)
    partial_tgt_sent = to_unicode_or_bust(raw_input(), sys.stdin.encoding).split()
    
    if partial_tgt_sent != []:
    
        print fill("Which source words were translated?", 79)
        translated = list(eval(raw_input()))
        translated_src_mask = [ i in translated for i in range(len(src_sent))]
        print translated_src_mask
        
        print fill("Which source word is aligned with the last translated word \"%s\"?" 
                                % (partial_tgt_sent[-1]), 79)    
        last_translated_index = eval(raw_input())
    else:
        partial_tgt_sent = None
    
    # instantiate a decoder with all the input data collected  
    decoder = Decoder(lm, rm, tm,
                      src_sent,
                      decoder_stack_threshold,
                      translated_src_mask, 
                      last_translated_index,
                      partial_tgt_sent           )
    
    # invoke decode() method to complete decoding
    decoder.decode()
    
    # DEBUG ONLY
#    print len(decoder._decoder_stacks[-1].decompose())
#    for hypo in decoder.decoder_stacks[-1]:
#        print hypo.last_n_targets(len(src_sent)), hypo.partial_score

    # print results
    print
    print fill("Translation suggestions:", 79)
    decoder.print_ranked_results(num_results);

def to_unicode_or_bust(obj, encoding='utf-8'):
    """Detects if object is a string and if so converts to unicode, if not 
    already.
    """
    if isinstance(obj, basestring):
        if not isinstance(obj, unicode):
            obj = unicode(obj, encoding)
    return obj

if __name__ == "__main__":
    main();







